Este documento está orientado a enseñar a renderizar documentos con RMarkdown sin, necesariamente, saber R.
El documento se ha creado para utilizarlo como material de apoyo en un workshop presencial, por lo que, si lo estás leyendo sin la explicación, es posible que haya cosas que no entiendas.
RMarkdown es una librería de R que es capaz de renderizar documentos escritos en el lenguaje de marcado ligero Markdown.
Dicho en cristiano, es algo que te permite crear documentos PDF o HTML (principalmente) desde una llamada en el lenguaje R.
Las principales ventajas de su uso son:
En este workshop no vamos a entrar ni a explicar como programar en R, ni Markdown en profundidad. Vamos a explicar las principales acciones que vas a utilizar y te invitamos a que indagues en los tutoriales, documentación y cheatsheets que hay disponibles en la comunidad.
En esta sección vamos a tratar los conceptos más básicos para hacer tu primer documento renderizado con RMarkdown.
De esta sección debes salir (o si te la quieres saltar, deberías saber):
Ataca a las secciones en las que necesites iniciarte/profundizar.
El acto de renderizar consiste en generar algo visual a partir de unas instrucciones. Eso es lo que hacemos al pasarle un documento como éste (.Rmd) al engine de RMarkdown.
Las instrucciones que les damos son variadas, entre ellas está el texto en Markdown, los trozos de código (chunks) y la cabecera del documento, que es la parte que vamos a abordar aquí.
Al principio de cada documento RMarkdown incluimos una cabecera con información básica para el motor de renderiado. Una cabecer habitual sería la siguiente:
---
author: "Pepito los palotes"
output: html_document
---
Si observas, verás que abrimos y cerramos la cabecera con un triple guión y, dentro, indicamos campos con la forma <clave>: <valor>
En este caso, identificamos dos parámetros que son:
html_document y pdf_document aunque hay más, como el Word y formato diapositivas.Esta cabecera se puede complicar más. De hecho, si entras al documento original que se ha utilizado para generar este documento, verás esto:
---
author: "Fernando Moreno Jabato"
output:
html_document:
toc: true
toc_float: true
df_print: paged
fig_width: 12
---
Aquí he añadido un conjunto de parámetros que, personalmente, me gusta utilizar como:
Mi recomendación personal es que uses, siempre que sea posible, la renderización a HTML, ya que te permite incluir elementos interactivos y pesa prácticamente lo mismo.
Según tu necesidad, modifica tu cabecera para crear el documento que necesites. Encontrarás múltiples cheatsheets con ayuda sobre esto.
A parte de la cabecera, necesitarás dar la orden de renderizar. Si acostumbras a usar RStudio, verás un botón en la parte superior que pone knitr.
Mi recomendación es que uses el comando de R (que es el que llama RStudio) directamente en tu código. También, para que te sea más fácil automatizar este proceso en tus scripts. El comando es
rmarkdow::render(<ficheroRmd>)
Tiene múltiples parámetros más este comando, aquí sólo hemos especificado el parámetro de entrada. Personalmente te recomiendo que sepas de la existencia de estos otros dos parámetros:
Ambos son especialmente útiles cuando utilizas una misma plantilla para generar diferentes informes, por ejemplo, un informe por muestra. La plantilla se llama igual, así que, si no especificas un fichero de salida (1), cada nuevo informe pisará al anterior aunque contengan información diferente.
De igual modo, los ficheros temporales se basan en el nombre de la plantilla, por lo que, si paralelizas la generación de N informes para N muestras, los ficheros temporales se mezclarán y la vas a liar parda.
Si quieres ver una llamada básica, tienes el ejemplo en el fichero scbi_ftutorial_rmarkdown.R que renderiza este documento.
Markdown va a ser el principal contenido de tus documentos, si es que no te dedicas a pegar figuras y ya. Por eso debes aprender los comandos de marcado más básicos.
Si en algún momento no te queda claro cómo se hace cada cosa, puedes ir a este apartado en el documento original (.Rmd) y ver cómo se aplica cada concepto.
Principalmente, si quieres usar la negrita, la cursiva, tachado o subíndice tienes que rodear la palabra/frase a la que deseas dar estilo con:
Hay otra forma de hacer el cursiva y el cursiva y negrita con asterisco simple y triple respectivamente. Pero es lioso y, dependiendo de la situación, puede ser una mala práctica.
Otra cosa que vas a hacer mucho,es crear listas. Esto es tan simple como, al principio de cada entrada de la lista utilices un símbolo más (+) o un guión (-) si quieres una lista sin números.
Si quieres una lista ordenada (con números), sólo tienes que ir poniendo los números seguidos de un punto (.) en vez del más o el guión.
IMPORTANTE: para que RMarkdown pille bien la lista, tienes que dejar una línea en blanco antes del primer elemento de la lista. Así mismo, debes dejar un espacio entre el indicado de cada elemento (+/-/
Si tienes dudas:
La principal gracia de estos documentos es incrustarles código. Para ello usamos los chunks.
Hay dos tipos de chunks:
El primero se crea englobando el código entre un único carcter de comilla invertida (`) y el segundo se hace con tres de éstas (y algo más…).
Ambos son muy útiles tanto para la parte estética, como para la parte funcional.
Me explico. Vamos a empezar haciendo chunks que no ejecutan código. Es decir, sólo nos va a servir para algo visual. De hecho, la palabra visual y chunk están en estilo grisáceo porque los he incluido como dos chunks inline que no ejecutan ningún código.
Del mismo modo, puedo incluir una entrada en bloque que no ejecuta ningún código, como he hecho antes para las cabeceras de los ficheros Rmd:
Esto es un chunk en bloque que no ejecuta nada
Si no lo has hecho hasta ahora, es el momento de que entres en el fichero original de Rmd que genera este documento para que empieces a ver qué he hecho.
Si sólo quieres la parte visual, no necesitas añadir ninguna configuación y tus chunks tendrán este aspecto:
\```
Esto es un chunk de bloque que no ejecuta código.
Pero sin el slash invertido (\) que si no, no te lo puedo pintar ;P
\```
Si vamos a ejecutar el código de su interior, tenemos que añadirle configuración. Esto se consigue incluyendo, entre llaves ({}) la información de configuración.
Estas llaves se posicionan justo al principio del chunk, colindante a las comillas simples.
Lo primero que se indica es el lenguaje en el que están codificadas las instrucciones. Lo más habitual, ya que esto es RMarkdown, es que lo ejecutes en R (r), pero también puedes usar Python (python) o Ruby (ruby) por dar unos ejemplos.
De esta manera, un chunk con código normalmente tendrá este aspecto
Chunk inline: Si vas al documento Rmd original, verás que esto lo ha escrito R
Chunk en bloque:
\```{r}
codigo
\```
Nota: verás que no te he puesto forma visual de un chunk inline. esto se debe a que el render los pilla incluso si intentas falsearlos. Lo siento, vas a tener que entrar en el documento Rmd…aunque ya deberías haberlo hecho.
Los parámetros más importantes que te recomiendo utilizar son:
Mi experiencia me dice que, el 99% de las veces vas a poner tus chunks de bloque con echo a FALSE.
Y lo gracioso del eval es que puedes asignarle el valor de forma dinámica usando una variable de R. De esa manera puedes no renderizar los primeros chunks de un informe cuando aún lo estás desarrollando. Eso es especialmente útil cuando tienes informes que son costosos de generar y estás desarrollandolo y lo ejecutas cada 10 segundos.
Ahora si, vamos a ejecutar código de verdad.
Un ejemplo tonto de R es cargar un set de datos que ya exista y vamos a pintar una gráfica.
Empezamos cargando los datos del dataset público Iris y mostramos un resumen de éste:
library(datasets)
data(iris)
summary(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
## Species
## setosa :50
## versicolor:50
## virginica :50
##
##
##
He dejado el código visible, pero si sólo te interesa el resumen, podrías poner el echo a false y quedaría más elegante.
Ahora, vamos a pintar una gráfica con estos datos:
plot(iris)
Como has podido ver, fácilmente he incluido una gráfica en el documento sin necesidad de exportarla a un PNG y luego pegarla a mano.
Llegados a este punto, the sky is the limit. Pero os voy a explicar alguna cosilla más en las secciones siguientes.
Vale, ahora vamos a hacer alguna cosilla que, no necesariamente es más complicado, pero queda muy bien en estos informes.
La primera de ellas es que, si renderizas a HTML, puedes incluir elementos dinámicos. De hecho, puedes programar directamente con elementos HTML, pero si estás haciendo este seminario, no deberías meterte en estos fregaos.
El caso es que hay varias librerías que ya incluyen elementos dinámicos. Por ejemplo,
Por ejemplo, el paquete rAmCharts te permite pintar fácilmente este histograma (prueba a pasar el ratón por encima):
rAmCharts::amHist(iris$Petal.Length)
Podemos hacer pijadas como esta visión 3D usando el paquete plotly (juega a arrastrar el objeto):
plotly::plot_ly(z = volcano, type = "surface")
O cosas chulas como esta red gestionada con visNetwork (prueba a mover los nodos):
# Me invento la red
nodes <- data.frame(id = 1:15, label = paste("Id", 1:15),
group=sample(LETTERS[1:3], 15, replace = TRUE))
edges <- data.frame(from = trunc(runif(15)*(15-1))+1,to = trunc(runif(15)*(15-1))+1)
# La pinto
suppressPackageStartupMessages(require(dplyr))
visNetwork::visNetwork(nodes,edges) %>% visNetwork::visOptions(highlightNearest = TRUE, selectedBy="group")
Esto son ejemplos. La comunidad de R es lo suficientemente grande como para que haya una solución a lo que tu estás buscando.
Recomendación: si no encuentras algo que te convenza, prueba a hacerte tu gráfico usando ggplot y pásaselo a la función ggplotly(<plot>). Puede que te sorprendas.
Una forma bonita de dejar las tablas en HTML, es usando el paquete DT. Aquí os dejo un código que permite aplciar filtros dinámicos en las columnas e incluso mostrar unos botones para descargar los datos en CSV o Excel. Porque si, esta es otra forma de pasarle la tabla de resultados a tus usuarios (;P)
DT::datatable(iris, filter = 'top', rownames = FALSE, extensions = c('Buttons','ColReorder'),
options = list(
colReorder = TRUE,
dom = 'lftBip',
buttons = c('copy', 'csv', 'excel')
))
Habrás notado que puedes hasta mover la distribución de columnas.
Es probable que identifiques secciones que se repiten en varios informes de plantillas diferentes. Si esto es así, tienes dos opciones:
Esta segunda opción es muy interesante porque, si modificas algo de esa sección, sólo tienes que hacerlo en un documento.
Para hacerlo, sólo tienes que usar la función knitr::knit_expandy pasarle la ruta al fichero Rmd. Luego sólo tienes que expandirlo con knitr::knit tal como se ha hecho en esta misma sección, míralo en el documento original (;P).
Entrar en el mundo de hacerte tus propias plantillas tiene una virtud y un defecto.
Si empiezas a desarrollar código, mi recomendación es que seas bueno poniendo todos y eleigiendo los nombres de los chunks y las variables.
Y recuerda la filosofía KISSS (Keep It Simple Stupid!)
No te asustes si entras en el fichero original (.Rmd) y descubres que esta sección entera, está generada de forma dinámica con código de R.
De hecho, este chunk está generado dinámicamente también
message(paste0('1+1 son: ',1+1))
## 1+1 son: 2
Esto es sólo para darte ideas. Pero cuidado que aquí hay dragones